import { useUserStore } from '@/store/modules/user'
import Axios, { AxiosError, AxiosInstance, AxiosRequestConfig } from 'axios'
import { HEAD_TOKEN } from '../constant'
import defaultConfig from './defaultConfig'
import { ResultData, httpMsgMapObject, httpMsgType } from './types'

export const httpMsgMap = {
  200: {
    title: '成功',
    type: 'success',
  },
  203: {
    title: '失败',
    type: 'warning',
  },
  999: {
    title: '异常错误',
    type: 'error',
  },
  403: {
    title: '身份失效',
    type: 'error',
  }
} as httpMsgMapObject



export class Interceptors {
  public instance: AxiosInstance

  constructor() {
    this.instance = Axios.create(defaultConfig)

    this.init()
  }

  // 请求拦截器
  requestInterceptors() {
    this.instance.interceptors.request.use((config) => {
      const userStore = useUserStore()
      config.headers[HEAD_TOKEN] = userStore.token

      return config
    }, (err: AxiosError) => {
      return Promise.reject(err)
    })
  }

  // 响应拦截器
  responseInterceptors() {
    this.instance.interceptors.response.use((response) => {
      const data = response.data as ResultData

      if (data.msg !== '' && (data.msg ?? false)) {
        ElNotification({
          title: httpMsgMap[data.code].title,
          message: data.msg,
          type: httpMsgMap[data.code].type as httpMsgType,
        })
      }

      return Promise.resolve(response.data)
    }, (err: AxiosError) => {
      const data = err.response?.data as ResultData

      // token问题
      if (data?.code === 403) {
        const userStore = useUserStore()

        userStore.resetAllUserData()
      }

      ElNotification({
        title: httpMsgMap[data?.code ?? 999].title,
        message: data?.msg ?? `后端错误: ${err?.response?.status} -> ${err?.response?.statusText}`,
        type: httpMsgMap[data?.code ?? 999].type as httpMsgType,
      })

      return Promise.reject(err)
    })
  }

  private init() {
    this.requestInterceptors()
    this.responseInterceptors()
  }

  get<T = any>(url: any) {
    return this.instance.get<ResultData<T>, ResultData<T>>(url)
  }

  post<T = any>(url: any, data?: any) {
    return this.instance.post<ResultData<T>, ResultData<T>>(url, data)
  }

  request<T>(config: AxiosRequestConfig) {
    return this.instance.request<ResultData<T>, ResultData<T>>(config)
  }


  getInterceptors() {
    return this.instance
  }
}
const instance = new Interceptors()

export default instance
